<?php
/**
 * Created by PhpStorm.
 * User: Kevin
 * Date: 2019/1/17
 * Time: 11:08
 */
namespace alipay;
use think\Controller;
//use alipay\aop\request\AlipayTradePagePayRequest;
//use alipay\aop\request\AlipayTradeRefundRequest;
//use alipay\aop\request\AlipayTradeQueryRequest;
//use alipay\aop\request\AlipayTradeFastpayRefundQueryRequest;
//use alipay\aop\request\AlipayTradeCloseRequest;
//use alipay\aop\AopClient;
class Alipay extends Controller
{
    public function _initialize()
    {
        require_once ROOT_PATH.'extend/alipay/AopSdk.php';
    }


    /**
     * 电脑网页支付
     * @param $out_trade_no 商户订单号，商户网站订单系统中唯一订单号，必填
     * @param $subject 订单名称，粗略描述用户的支付目的。必填
     * @param $total_amount 付款金额，整形，此处单位为元，精确到小数点后2位，不能超过1亿元 必填
     * @param $body 商品描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元" 可空
     * @param $return_url 同步跳转地址，公网可以访问
     * @param $notify_url 异步通知地址，公网可以访问，回调数据接口
     */
    public function pagePay($out_trade_no,$subject,$total_amount,$body,$return_url,$notify_url){
        require_once ROOT_PATH.'extend/alipay/aop/request/AlipayTradePagePayRequest.php';
        $bizContentarr = [
            'body'=>$body,
            'subject'=>$subject,
            'total_amount'=>$total_amount,
            'out_trade_no'=>$out_trade_no,
            'timeout_express'=>'15m',// (推荐使用，相对时间) 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m
            'product_code'=>"FAST_INSTANT_TRADE_PAY"
        ];
        $biz_content = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
        //打印业务参数
        $this->writeLog($biz_content);

        $request = new \AlipayTradePagePayRequest();
        $request->setNotifyUrl($notify_url); //异步通知地址，公网可以访问
        $request->setReturnUrl($return_url); //同步跳转地址，公网可以访问
        $request->setBizContent ( $biz_content );
        $aop = $this->getAopClient();
        $result = $aop->pageExecute($request,"post");
        //打开后，将报文写入log文件
        $this->writeLog("response: ".var_export($result,true));
        return $result;
    }

    /**
     * 退款
     * @param $trade_no //支付宝交易号  (支付宝交易号和商户订单号二选一，默认支付宝交易号)
     * @param $refund_amount //需要退款的金额，该金额不能大于订单金额，必填
     * @param $refund_reason //退款的原因说明
     * @param $out_request_no //标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
     * @param $out_trade_no//商户订单号，商户网站订单系统中唯一订单号
     */
    public function refund($trade_no,$refund_amount,$refund_reason,$out_request_no = '',$out_trade_no = ''){
        require_once ROOT_PATH.'extend/alipay/aop/request/AlipayTradeRefundRequest.php';
        $bizContentarr= [
            'trade_no'=>$trade_no,
            'refund_amount'=>$refund_amount,
            'refund_reason'=>$refund_reason,
            'out_request_no'=>$out_request_no,
            'out_trade_no'=>$out_trade_no
        ];
        $biz_content = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
        //打印业务参数
        $this->writeLog($biz_content);
        $request = new \AlipayTradeRefundRequest();
        $request->setBizContent ( $biz_content );
        $aop = $this->getAopClient();
        $result = $aop->Execute($request);
        //打开后，将报文写入log文件
        $this->writeLog("response: ".var_export($result,true));
        return $result;
    }


    /**
     * 交易查询
     * @param $trade_no//支付宝交易号  (支付宝交易号和商户订单号二选一，默认支付宝交易号)
     * @param $out_trade_no//商户订单号，商户网站订单系统中唯一订单号
     */
    public function query($trade_no,$out_trade_no = ''){
        require_once ROOT_PATH.'extend/alipay/aop/request/AlipayTradeQueryRequest.php';
        $bizContentarr= [
            'trade_no'=>$trade_no,
            'out_trade_no'=>$out_trade_no
        ];
        $biz_content = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
        //打印业务参数
        $this->writeLog($biz_content);
        $request = new \AlipayTradeQueryRequest();
        $request->setBizContent ( $biz_content );
        $aop = $this->getAopClient();
        $result = $aop->Execute($request);
        //打开后，将报文写入log文件
        $this->writeLog("response: ".var_export($result,true));
        return $result;
    }


    /**
     * 退款查询
     * @param $trade_no//支付宝交易号  (支付宝交易号和商户订单号二选一，默认支付宝交易号)
     * @param $out_trade_no//商户订单号，商户网站订单系统中唯一订单号
     * @param $out_request_no//请求退款接口时，传入的退款请求号，如果在退款请求时未传入，则该值为创建交易时的外部交易号，必填
     */
    public function refundQuery($trade_no,$out_request_no,$out_trade_no = ''){
        require_once ROOT_PATH.'extend/alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php';
        $bizContentarr= [
            'trade_no'=>$trade_no,
            'out_trade_no'=>$out_trade_no,
            'out_request_no'=>$out_request_no
        ];
        $biz_content = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
        //打印业务参数
        $this->writeLog($biz_content);
        $request = new \AlipayTradeFastpayRefundQueryRequest();
        $request->setBizContent ( $biz_content );
        $aop = $this->getAopClient();
        $result = $aop->Execute($request);
        //打开后，将报文写入log文件
        $this->writeLog("response: ".var_export($result,true));
        return $result;
    }

    /**
     * 关闭交易
     * @param $trade_no//支付宝交易号  (支付宝交易号和商户订单号二选一，默认支付宝交易号)
     * @param $out_trade_no//商户订单号，商户网站订单系统中唯一订单号
     */
    public function close($trade_no,$out_trade_no = ''){
        require_once ROOT_PATH.'extend/alipay/aop/request/AlipayTradeCloseRequest.php';
        $bizContentarr= [
            'trade_no'=>$trade_no,
            'out_trade_no'=>$out_trade_no
        ];
        $biz_content = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
        //打印业务参数
        $this->writeLog($biz_content);
        $request = new \AlipayTradeCloseRequest();
        $request->setBizContent ( $biz_content );
        $aop = $this->getAopClient();
        $result = $aop->Execute($request);
        //打开后，将报文写入log文件
        $this->writeLog("response: ".var_export($result,true));
        return $result;
    }


    /**
     * 支付宝验签
     * @return bool
     */
    public function checkReturn($return)
    {
        require_once ROOT_PATH.'extend/alipay/aop/AopClient.php';
        $aop = new \AopClient();
        $aop->alipayrsaPublicKey = config('alipay.aliPublicKey');
        $flag = $aop->rsaCheckV1($return, NULL, "RSA2");
        if($flag) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 签名
     * @return AopClient
     */
    public function getAopClient(){
        require_once ROOT_PATH.'extend/alipay/aop/AopClient.php';
        $aop = new \AopClient ();
        $aop->gatewayUrl = config('alipay.gatewayUrl');//支付宝网关地址
        $aop->appId = config('alipay.appId');//应用id
        $aop->rsaPrivateKey =  config('alipay.rsaPrivateKey');//商户私钥
        $aop->alipayrsaPublicKey = config('alipay.aliPublicKey');//支付宝公钥
        $aop->apiVersion ="1.0";
        $aop->postCharset = "UTF-8";
        $aop->format= "json";
        $aop->signType= "RSA2";
        // 开启页面信息输出
        $aop->debugInfo=true;
        return $aop;
    }


    /**
     * 请确保项目文件有可写权限，不然打印不了日志。
     */
    function writeLog($text) {
        // $text=iconv("GBK", "UTF-8//IGNORE", $text);
        //$text = characet ( $text );
        file_put_contents ( ROOT_PATH."public/alipay_log.txt", date ( "Y-m-d H:i:s" ) . "  " . $text . "\r\n", FILE_APPEND );
    }
}